/*Copyright ©2015 TommyLemon(https://github.com/TommyLemon)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
limitations under the License.*/

package zuo.biao.library.manager;

import ohos.eventhandler.EventHandler;
import ohos.eventhandler.EventRunner;
import zuo.biao.library.util.Log;
import zuo.biao.library.util.StringUtil;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**线程管理类
 * @author Lemon
 * @use ThreadManager.getInstance().runThread(...);
 * 		在使用ThreadManager的Context被销毁前ThreadManager.getInstance().destroyThread(...);
 *      在应用退出前ThreadManager.getInstance().finish();
 */
public class ThreadManager {
    private static final String TAG = "ThreadManager";

    private Map<String, ThreadBean> threadMap;

    private ThreadManager() {
        threadMap = new HashMap<String, ThreadBean>();
    }

    private static ThreadManager instance = new ThreadManager();

    public static ThreadManager getInstance() {
        return instance;
    }

    /**运行线程
     * @param name 线程名
     * @param runnable r
     * @return 线程
     */
    public EventHandler runThread(String name, Runnable runnable) {
        if (StringUtil.isNotEmpty(name, true) == false || runnable == null) {
            Log.error(TAG, "runThread  StringUtil.isNotEmpty(name, true) == false || runnable == null >> return");
            return null;
        }
        name = StringUtil.getTrimedString(name);
        Log.debug(TAG, "\n runThread  name = " + name);

        EventHandler handler = getHandler(name);
        if (handler != null) {
            Log.warn(TAG, "handler != null >>  destroyThread(name);");
            destroyThread(name);
        }

        EventRunner thread = EventRunner.create(name);
        // 创建一个HandlerThread并启动它
        handler = new EventHandler(EventRunner.getMainEventRunner()); // 使用HandlerThread的looper对象创建Handler
        handler.postTask(runnable); // 将线程post到Handler中

        threadMap.put(name, new ThreadBean(name, thread, runnable, handler));

        Log.debug(TAG, "runThread  added name = " + name + "; threadMap.size() = " + threadMap.size());
        return handler;
    }

    /**获取线程Handler
     * @param name n
     * @return 线程
     */
    private EventHandler getHandler(String name) {
        ThreadBean tb = getThread(name);
        return tb == null ? null : tb.getHandler();
    }

    /**获取线程
     * @param name n
     * @return 线程
     */
    private ThreadBean getThread(String name) {
        return name == null ? null : threadMap.get(name);
    }

    /**销毁线程
     * @param nameList n
     */
    public void destroyThread(List<String> nameList) {
        if (nameList != null) {
            for (String name : nameList) {
                destroyThread(name);
            }
        }
    }
    /**销毁线程
     * @param name n
     */
    public void destroyThread(String name) {
        destroyThread(getThread(name));
    }
    /**销毁线程
     * @param tb t
     */
    private void destroyThread(ThreadBean tb) {
        if (tb == null) {
            Log.error(TAG, "destroyThread  tb == null >> return;");
            return;
        }

        destroyThread(tb.getHandler(), tb.getRunnable());
        if (tb.getName() != null) {
            threadMap.remove(tb.getName());
        }
    }
    /**销毁线程
     * @param handler handler
     * @param runnable runnable
     */
    public void destroyThread(EventHandler handler, Runnable runnable) {
        if (handler == null || runnable == null) {
            Log.error(TAG, "destroyThread  handler == null || runnable == null >> return;");
            return;
        }

        try {
            handler.removeTask(runnable);
        } catch (Exception e) {
            Log.error(TAG, "onDestroy try { handler.removeCallbacks(runnable);...  >> catch  : " + e.getMessage());
        }
    }

    /**结束ThreadManager所有进程
     */
    public void finish() {
        if (threadMap == null || threadMap.keySet() == null) {
            Log.debug(TAG, "finish  threadMap == null || threadMap.keySet() == null >> threadMap = null; >> return;");
            threadMap = null;
            return;
        }
        List<String> nameList = new ArrayList<String>(threadMap.keySet()); // 直接用Set在系统杀掉应用时崩溃
        if (nameList != null) {
            for (String name : nameList) {
                destroyThread(name);
            }
        }
        threadMap = null;
        Log.debug(TAG, "\n finish  finished \n");
    }

    /**线程类
     */
    private static class ThreadBean {
        private String name;

        private EventRunner thread;

        private Runnable runnable;
        private EventHandler handler;

        public ThreadBean(String name, EventRunner thread, Runnable runnable, EventHandler handler) {
            this.name = name;
            this.thread = thread;
            this.runnable = runnable;
            this.handler = handler;
        }

        public String getName() {
            return name;
        }

        public Runnable getRunnable() {
            return runnable;
        }

        public EventHandler getHandler() {
            return handler;
        }
    }
}
